在Spark上进行两个大数据集的匹配

分布式框架Spark把任务划分到各个子节点进行处理,可以有效利用小机器的CPU来处理大规模数据集。但是Spark也存在局限性,在某些问题的处理上会力不从心,例如两个大数据集的匹配。出现这种问题的原因主要是分布式系统的优势在于机器的数量,子节点的CPU和内存通常配置较低。

问题描述:如果有两个大数据集A和B,假设A有几千万条数据,B有几百万条数据,需要把B中的每一条数据和A中的每一条数据进行比较。下面列举几种解决的方法:

(1)直接把A和B join后两两计算,这样会导致很大的shuffle,千万*百万=十万亿的数量级。

(2)A存到HDFS上,B进行切分,比如每100条起个spark job跑一下。这种方法可以解决大多数问题,比如可以起个spark streaming,然后把B中的数据分片丢进去,再和A中的数据join做运算。这种方式会有较多的shuffle,千万*百=十亿的数量级,所以可以先把数据collect,然后再和A数据做比较。

(3)通常driver可用的内存会比较大,可以先用collect函数把B载入内存,然后把B中的数据分片broadcast到工作节点上,例如每个分片B’包含100条数据,在工作节点上,B’是在内存中的,可以直接和A数据做比较,而不需要join。例如代码:

Broadcast<List<String>> broadcast;
JavaRDD<String> totalResult = null;
int count = 0;
List<String> tempArticleList = new ArrayList<String>();
for (String article : BCollect) { //BCollect:B数据集collect结果
    tempArticleList.add(article);
    count++;

    if (tempArticleList.size() >= 100) {
    broadcast = sc.broadcast(tempArticleList);
    logger.info("size of broadcast:" + tempArticleList.size());
    // baseRddx--A数据集
    JavaRDD<String> resultRDDx = baseRddx.flatMap(new CompareArticle());  
    if (totalResult == null) {
        totalResult = resultRDDx;
    } else {
        totalResult = totalResult.union(resultRDDx);
    }
    count = 0;
    tempArticleList = new ArrayList<String>();
    }
}
    //把剩下的数据处理掉
    if (tempArticleList.size() > 0) {
        broadcast = sc.broadcast(tempArticleList);
        logger.info("size of broadcast:" + tempArticleList.size());
        JavaRDD<String> resultRDDx = baseRddx.flatMap(new CompareArticle());
        if (totalResult == null) {
            totalResult = resultRDDx;
        } else {
            totalResult = totalResult.union(resultRDDx);
        }
    }
class CompareArticle implements FlatMapFunction<String, String> {
        @Override
        public Iterable<String> call(String line) throws Exception {
            List<String> resultList = new ArrayList<String>();
            //B数据集分块
            List<String> articleList = broadcast.getValue();
            ...
        }
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值